import os
import re
import ipaddress
from datetime import datetime
from src.core.database import DatabaseConnector
from src.models.ipdomain import IPDomain
from src.io.file_exporter import FileExporter
from src.io.csv_importer import CsvImporter
from src.core.dbhelper import DBHelper

class IPDomainCommand:
    """IP域名映射命令处理类"""
    
    def __init__(self, db_connector=None, subparsers=None):
        """初始化IP域名映射命令处理器"""
        self.db_connector = db_connector or DatabaseConnector()
        self.db_helper = DBHelper(self.db_connector)
        self.file_exporter = FileExporter()
        self.csv_importer = CsvImporter(self.db_connector)
        self.arg_parser = self.setup_parser(subparsers)
    
    def setup_parser(self, subparsers):
        """设置IP域名映射管理命令行参数解析器"""
        # ipdomain命令组
        ipdomain_parser = subparsers.add_parser('ipdomain', help='IP域名映射管理相关命令', description='IP域名映射管理相关的所有操作')
        ipdomain_subparsers = ipdomain_parser.add_subparsers(dest='ipdomain_command', help='IP域名映射管理子命令')

        # ipdomain help命令组
        ipdomain_subparsers.add_parser('help', help='显示IP域名映射管理命令帮助')

        # ipdomain add命令组
        ipdomain_add_parser = ipdomain_subparsers.add_parser('add', help='添加IP域名映射')
        ipdomain_add_parser.add_argument('ip', help='IP地址')
        ipdomain_add_parser.add_argument('domain', help='域名')

        # ipdomain get命令组
        ipdomain_get_parser = ipdomain_subparsers.add_parser('get', help='获取IP域名映射')
        ipdomain_get_parser.add_argument('target', help='IP地址或域名')

        # ipdomain getall命令组
        ipdomain_getall_parser = ipdomain_subparsers.add_parser('getall', help='获取所有IP域名映射')
        ipdomain_getall_parser.add_argument('-o', '--output', nargs='?', const=True, help='导出文件路径')
        ipdomain_getall_parser.add_argument('-e', '--extension', choices=['json', 'csv'], default='csv', help='导出文件格式，默认csv')

        # ipdomain delete命令组
        ipdomain_delete_parser = ipdomain_subparsers.add_parser('delete', help='删除IP域名映射')
        ipdomain_delete_parser.add_argument('ip', help='IP地址')
        ipdomain_delete_parser.add_argument('domain', help='域名')

        # ipdomain import命令组
        ipdomain_import_parser = ipdomain_subparsers.add_parser('import', help='导入IP域名映射数据')
        ipdomain_import_parser.add_argument('file_path', help='CSV文件路径')
        ipdomain_import_parser.add_argument('--ip-column', help='IP列的索引或名称，默认为列名称为"ip"的列，或第一列', default='ip')
        ipdomain_import_parser.add_argument('--domain-column', help='域名列的索引或名称，默认为列名称为"domain"的列，或第二列', default='domain')
        
        return ipdomain_parser


    def handle_command(self, args):
        """处理IP域名映射命令"""
        command = args.ipdomain_command
        if command == 'help':
            self.show_ipdomain_help()
        elif command == 'add':
            self.add_ipdomain(args.ip, args.domain)
        elif command == 'get':
            self.get_ipdomain(args.target)
        elif command == 'getall':
            export_path = args.output
            extension = args.extension
            self.get_all_ipdomains(export_path=export_path, extension=extension)
        elif command == 'delete':
            self.delete_ipdomain(args.ip, args.domain)
        elif command == 'import':
            self.import_ipdomains(args.file_path, args.ip_column, args.domain_column)
        else:
            print(f"未知的IP域名映射命令: {command}")
            self.show_ipdomain_help()
    
    def show_ipdomain_help(self):
        """显示IP域名映射管理命令帮助信息"""
        self.arg_parser.print_help()
    
    def is_valid_domain(self, domain):
        """验证域名格式是否有效"""
        # 简单的域名验证正则表达式
        pattern = r'^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$'
        return re.match(pattern, domain) is not None
    
    def add_ipdomain(self, ip, domain):
        """添加IP和域名的映射关系"""
        try:
            ipdomain = self.db_helper.get_or_add_domain(ip, domain)
            if '_is_new' in ipdomain and ipdomain['_is_new']:
                print(f"成功添加IP域名映射关系：")
                print(f"  IP地址: {ip}")
                print(f"  域名: {domain}")
            else:
                print(f"IP '{ip}' 和域名 '{domain}' 的映射关系已存在！")
        except Exception as e:
            print(f"添加IP域名映射关系失败: {e}") 
    
    def get_ipdomain(self, target):
        """获取IP和域名的映射关系"""
        results = []
        export_data = []
        
        try:
            # 尝试作为IP地址处理
            ipaddress.ip_address(target)
            is_ip = True
        except ValueError:
            is_ip = False
        
        if is_ip:
            # 按IP地址查询
            sql = "SELECT * FROM ipdomains WHERE ip = %s ORDER BY domain"
            params = (target,)
            query_type = "IP地址"
            display_value = target
        else:
            # 按域名查询
            sql = "SELECT * FROM ipdomains WHERE domain = %s ORDER BY ip"
            params = (target,)
            query_type = "域名"
            display_value = target
        
        results = self.db_connector.fetchall(sql, params)
        if len(results) == 0:
            print(f"未找到 {query_type} '{display_value}' 的映射关系！")
            return
        
        # 准备导出数据
        for row in results:
            export_item = {
                'ip': row['ip'],
                'domain': row['domain'],
                'create_time': row['create_time']
            }
            # 转换datetime对象为字符串
            if 'create_time' in export_item and isinstance(export_item['create_time'], datetime):
                export_item['create_time'] = export_item['create_time'].strftime('%Y-%m-%d %H:%M:%S')
            export_data.append(export_item)
        
        # 显示映射关系
        print(f"{query_type} '{display_value}' 的映射关系 ({len(results)} 个):")
        print("{:<10} {:<15} {:<30} {:<20}".format(
            "映射ID", "IP地址", "域名", "创建时间"
        ))
        print("=" * 65)
        
        for row in results:
            id = row['id']
            ip = row['ip']
            domain = row['domain']
            create_time = row['create_time']
            
            # 转换datetime对象为字符串
            if isinstance(create_time, datetime):
                create_time = create_time.strftime('%Y-%m-%d %H:%M:%S')
            
            print("{:<10} {:<15} {:<30} {:<20}".format(
                id, ip, domain, create_time
            ))
    
    def delete_ipdomain(self, ip, domain):
        """删除IP和域名的映射关系"""
        # 验证IP地址格式
        try:
            ipaddress.ip_address(ip)
        except ValueError:
            print(f"错误：无效的IP地址格式: {ip}")
            return

        # 验证域名格式
        if not self.is_valid_domain(domain):
            print(f"错误：无效的域名格式: {domain}")
            return
        
        # 检查映射关系是否存在
        sql = "SELECT * FROM ipdomains WHERE ip = %s AND domain = %s"
        result = self.db_connector.fetchone(sql, (ip, domain))
        if not result:
            print(f"错误：IP '{ip}' 和域名 '{domain}' 的映射关系不存在！")
            return
        
        # 删除映射关系
        sql = "DELETE FROM ipdomains WHERE ip = %s AND domain = %s"
        try:
            self.db_connector.execute_query(sql, (ip, domain))
            print(f"成功删除IP域名映射关系：")
            print(f"  IP地址: {ip}")
            print(f"  域名: {domain}")
        except Exception as e:
            print(f"删除IP域名映射关系失败: {e}")
    
    def import_ipdomains(self, file_path, ip_column='ip', domain_column='domain'):
        """从CSV文件导入IP域名映射数据"""
        # 验证文件是否存在
        if not os.path.exists(file_path):
            print(f"错误: 文件 {file_path} 不存在！")
            return
        
        # 检查文件扩展名
        file_ext = os.path.splitext(file_path)[1].lower()
        if file_ext != '.csv':
            print(f"错误: 只支持CSV文件格式，当前文件格式为 '{file_ext}'")
            return
        
        try:
            success_count, failed_count = self.csv_importer.import_ipdomains_from_csv(file_path, ip_column, domain_column)
            print(f"IP域名映射导入完成: 成功 {success_count} 个, 失败 {failed_count} 个")
        except Exception as e:
            print(f"导入IP域名映射时发生错误: {str(e)}")
    
    def get_all_ipdomains(self, export_path=None, extension=None):
        """获取所有IP域名映射关系"""
        # 查询所有映射关系
        sql = "SELECT * FROM ipdomains ORDER BY ip, domain"
        mappings = self.db_connector.fetchall(sql)
        if len(mappings) == 0:
            print("暂无IP域名映射关系！")
            return
        
        # 准备导出数据
        export_data = []
        for mapping in mappings:
            export_item = {
                'ip': mapping['ip'],
                'domain': mapping['domain'],
                'create_time': mapping['create_time']
            }
            # 转换datetime对象为字符串
            if 'create_time' in export_item and isinstance(export_item['create_time'], datetime):
                export_item['create_time'] = export_item['create_time'].strftime('%Y-%m-%d %H:%M:%S')
            export_data.append(export_item)
        
        # 导出数据
        if export_path is not None:
            actual_path = None if export_path is True else export_path
            self.file_exporter.export_data(export_data, actual_path, 'all_ipdomains', extension)
            return
        
        # 显示映射关系列表
        print(f"共有 {len(mappings)} 个IP域名映射关系:")
        print("{:<10} {:<15} {:<30} {:<20}".format(
            "ID", "IP地址", "域名", "创建时间"
        ))
        print("=" * 75)
        
        for row in mappings:
            id = row['id']
            ip = row['ip']
            domain = row['domain']
            create_time = row['create_time']
            
            # 转换datetime对象为字符串
            if isinstance(create_time, datetime):
                create_time = create_time.strftime('%Y-%m-%d %H:%M:%S')
            
            print("{:<10} {:<15} {:<30} {:<20}".format(
                id, ip, domain, create_time
            ))
        print(f"共有 {len(mappings)} 个IP域名映射关系")